﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using starLiGHT.Physic.TwoD;
using Microsoft.Xna.Framework;

#endregion

#region COPYRIGHT

/*
    Copyright (c) 2008, 2009, 2010 
        Roland Rosenkranz (Glatzemann@email.de)
*/

#endregion

#region LICENSE

/*
    This file is part of starLiGHT.Collision.

    starLiGHT.Collision is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    starLiGHT.Collision is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with starLiGHT.Collision.  If not, see <http://www.gnu.org/licenses/>.

    
    ADDITIONAL (commercial) LICENSES for starLiGHT.Collision are available on request.
*/

#endregion

#region Version Stuff
// **************[ starLiGHT.Engine SVN ]**********************
// * $Rev:: 1486                  $:  Revision of last commit *
// * $Author:: glatzemann         $:  Author of last commit   *
// * $Date:: 2010-10-08 15:55:47 #$:  Date of last commit     *
// ************************************************************
#endregion

namespace starLiGHT.Physic
{
    /// <summary>
    /// This is a simplest joint in the physic system. It maintains two points on two bodies constant.
    /// </summary>
    /// <remarks>
    /// When you specify a distance joint the two connected bodies should already be in place.
    /// </remarks>
    public class PrismaticJoint2D : Joint2D
    {
        #region Constructors
        /// <summary>
        /// Creates a new PrismaticJoint. The initial relative position is zero. The 
        /// anchor point is at the first body's center of mass and the prismatic angle 
        /// allows only vertical movement.
        /// </summary>
        /// <param name="body1">"Left" body to connect by the prismatic joint.</param>
        /// <param name="body2">"Right" body to connect by the prismatic joint.</param>
        public PrismaticJoint2D(RigidBody2D body1, RigidBody2D body2)
        {
            PrismaticJointDef jointDef = new PrismaticJointDef();
            jointDef.Initialize(body1.Body, body2.Body, body1.Position, Vector2.UnitY);
            jointDef.collideConnected = false;

            base.Joint = PhysicSystem2D.Instance.World.CreateJoint(jointDef);

            PhysicSystem2D.Instance.managedJoints.Add(this);
        }

        /// <summary>
        /// Creates a new PrismaticJoint. The initial relative position is zero. The 
        /// prismatic angle allows only vertical movement.
        /// </summary>
        /// <param name="body1">"Left" body to connect by the prismatic joint.</param>
        /// <param name="body2">"Right" body to connect by the prismatic joint.</param>
        /// <param name="worldAnchor">Anchor point which is used to connect the bodies in world coordinates.</param>
        public PrismaticJoint2D(RigidBody2D body1, RigidBody2D body2, Vector2 worldAnchor)
        {
            PrismaticJointDef jointDef = new PrismaticJointDef();
            jointDef.Initialize(body1.Body, body2.Body, worldAnchor, Vector2.UnitY);
            jointDef.collideConnected = false;

            base.Joint = PhysicSystem2D.Instance.World.CreateJoint(jointDef);

            PhysicSystem2D.Instance.managedJoints.Add(this);
        }

        /// <summary>
        /// Creates a new PrismaticJoint. The initial relative position is zero.
        /// </summary>
        /// <param name="body1">"Left" body to connect by the prismatic joint.</param>
        /// <param name="body2">"Right" body to connect by the prismatic joint.</param>
        /// <param name="worldAnchor">Anchor point which is used to connect the bodies in world coordinates.</param>
        /// <param name="worldAxis">Limited axis.</param>
        public PrismaticJoint2D(RigidBody2D body1, RigidBody2D body2, Vector2 worldAnchor, Vector2 worldAxis)
        {
            PrismaticJointDef jointDef = new PrismaticJointDef();
            jointDef.Initialize(body1.Body, body2.Body, worldAnchor, worldAxis);
            jointDef.collideConnected = false;

            base.Joint = PhysicSystem2D.Instance.World.CreateJoint(jointDef);

            PhysicSystem2D.Instance.managedJoints.Add(this);
        }

        #endregion

        /// <summary>
        /// The internal joint of the physic system.
        /// </summary>
        public new PrismaticJoint Joint
        {
            get { return base.Joint as PrismaticJoint; }
        }

        public void SetLimits(float lower, float upper)
        {
            Joint.SetLimits(lower, upper);
        }

        public float LowerLimit
        {
            get { return Joint.GetLowerLimit(); }
            set { Joint.SetLimits(value, UpperLimit); }
        }

        public float UpperLimit
        {
            get { return Joint.GetUpperLimit(); }
            set { Joint.SetLimits(LowerLimit, value); }
        }

        public bool LimitsEnabled
        {
            get { return Joint.IsLimitEnabled(); }
            set { Joint.m_enableLimit = value; }
        }
    }
}
